﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using BusinessRule.Common;
using BusinessRule.Business;
using BusinessRule.DTO;
using DatabaseAccess.DBUtility;
using System.Threading.Tasks;
using System.Configuration;
//Description:自动开卡定时任务处理类
//Copyright (c) : 通力凯顿（北京）系统集成有限公司
//Writer:zhangrj
//create Date:2024-01-09
//Rewriter:
//Rewrite Date:

namespace MESScheduledTask
{
    public class AutoStartContainerTask
    {
        private AutoStartContainerBusiness autoStartBusiness = new AutoStartContainerBusiness();
        public static readonly int maxParallelSync = Convert.ToInt32(ConfigurationManager.AppSettings["maxParallelSync"].ToString());//最大并行任务数
        private string serverAPIUserName = ConfigurationManager.AppSettings["ServerAPIUserName"].ToString();//camstarAPI用户名
        private string serverAPIPassword = ConfigurationManager.AppSettings["ServerAPIPassword"].ToString();//camstarAPI密码

        /// <summary>
        /// 执行任务
        /// </summary>
        /// <param name="taskList"></param>
        public void RunTaskSync(List<string> taskList)
        {
            //获取需要启动的任务
            DataTable dt = CommonHelper.GetNeedExecuteTask(CommonHelper.TaskTypeEnum.自动开卡);
            List<Task> tl = new List<Task>();

            foreach (DataRow dr2 in dt.Rows)
            {//开始循环定时任务
                var tempDt = dt.Clone();
                tempDt.ImportRow(dr2);
                var dr = tempDt.Rows[0];//此处必须要给局部变量赋值

                if (taskList.Count >= maxParallelSync)
                {
                    LogHelp.WriteLog("当前正在执行的任务数为：" + taskList.Count.ToString() + " 已达到最大并行限制----------------------------------------------------------------------");
                    break;
                }
                if (taskList.Contains(dr["scheduledtaskid"].ToString()))//已在任务中
                    continue;

                taskList.Add(dr["scheduledtaskid"].ToString());//添加到list中

                tl.Add(Task.Factory.StartNew(() =>
                {
                    try
                    {
                        DealAutoStartTask(dr);
                    }
                    catch (Exception ex)
                    {
                        LogHelp.WriteError(dr["taskname"].ToString() + "定时计算异常", ex);
                        CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "3", ex.Message + ex.StackTrace, "1");
                        return;
                    }
                    finally
                    {
                        LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 执行完毕，移除队列");
                        taskList.Remove(dr["scheduledtaskid"].ToString());
                    }
                }, TaskCreationOptions.LongRunning));

            }
            //本次产生的task，需要等待完毕
            Task.WaitAll(tl.ToArray());
        }

        /// <summary>
        /// 处理单个任务
        /// </summary>
        /// <param name="dr"></param>
        public void DealAutoStartTask(DataRow dr)
        {
            if (dr["type"].ToString() == "自动未执行")
            {
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "2", "", "1");//开始执行
            }
            //Dictionary<string, string> dicAttr = CommonHelper.GetTaskAttr(dr["ScheduledTaskId"].ToString());//获取定时任务的属性

            DataTable dtCreateEmp = CommonHelper.GetCreateEmp(dr["factoryid"].ToString());//获取开卡人
            if (dtCreateEmp.Rows.Count == 0)
            {
                LogHelp.WriteLog(string.Format("分厂：{0}，任务：{1} 执行完毕，分厂未配置开卡人", dr["factoryname"].ToString(), dr["taskname"].ToString()));
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", " 任务执行完毕，分厂未配置开卡人", "1");
                return;
            }
            uMESProcessResult res = autoStartBusiness.GetNotStartContainerOrderInfo(new Dictionary<string, string> { { "FactoryID", dr["factoryid"].ToString() } }, false);
            if (!res.Result)
            {
                LogHelp.WriteLog(string.Format("分厂：{0}，任务：{1} 查询分厂订单数据报错，原因：{2}", dr["factoryname"].ToString(), dr["taskname"].ToString(), res.Message));
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", " 任务执行完毕，查询分厂订单数据报错，原因：" + res.Message, "1");
                return;
            }
            string createEmpID = dtCreateEmp.Rows[0]["employeeid"].ToString(); //开卡人ID
            string createEmpName = dtCreateEmp.Rows[0]["employeename"].ToString(); //开卡人编号
            string fullName = dtCreateEmp.Rows[0]["fullname"].ToString(); //开卡人姓名
            int scount = 0, ecount = 0;//成功条数，失败条数
            DataTable dtOrder = res.DBTable;
            LogHelp.WriteLog(string.Format("分厂：{0}，任务：{1}开始执行，执行订单总数：{2}-------------------------------------------------------------", dr["factoryname"].ToString(), dr["taskname"].ToString(), dtOrder.Rows.Count));
            CommonHelper.UpdateTaskLogStartDate(dr["ScheduledTaskId"].ToString()); //更新定时任务日志的开始时间为当前时间
            for (int i = 0; i < dtOrder.Rows.Count; i++)
            {
                //检查是否提前终止
                if (DatabaseHelper.GetSingle(string.Format(@"select 1 from ScheduledTaskLogs sl
                            where sl.scheduledtaskid='{0}' and sl.islatest=1 and sl.taskexeendtime is not null", dr["ScheduledTaskId"].ToString())) != null)
                {
                    break;
                }
                DataRow drOrder = dtOrder.Rows[i];
                Tuple<AutoStartContainerParam, bool, string> mapData = GetOrderMappingData(drOrder);
                if (!mapData.Item2)
                {
                    ecount++;
                    LogHelp.WriteLog(string.Format("分厂：{0}，任务：{1} 的第{2}个订单：{3}转换报错，原因：{4}", dr["factoryname"].ToString(), dr["taskname"].ToString(), (i + 1).ToString(), dr["mfgordername"].ToString(), mapData.Item3));
                    continue;
                }
                AutoStartContainerParam param = mapData.Item1;
                CurrentUserInfo user = new CurrentUserInfo();//固定开卡人
                user.APIUserName = serverAPIUserName;
                user.APIPassword = serverAPIPassword;
                user.Factory = dr["factoryname"].ToString();//动态取开卡分厂
                user.FactoryID = dr["factoryid"].ToString();
                user.EmployeeID = createEmpID;
                user.EmployeeName = createEmpName;
                user.FullName = fullName;
                res = autoStartBusiness.OneKeyStartContainerInfo(param, user);
                if (res.Result)
                {
                    scount++;
                }
                else
                {
                    ecount++;
                    if (res.ReturnData == null)
                    {
                        //插入开卡出错日志
                        autoStartBusiness.CreateAutoStartErrorInfo(new Dictionary<string, string> { { "MfgOrderID",param.MfgOrderID},
                                                { "MfgOrderName",param.MfgOrderName},
                                                { "ProductName",param.ProductName},
                                                { "Notes",res.Message},
                                                { "CreateEmpID",user.EmployeeID},
                                                { "FactoryID",user.FactoryID}});
                    }
                }
                LogHelp.WriteLog(string.Format("分厂：{0}，任务：{1} 的第{2}个订单：{3}{4}", dr["factoryname"].ToString(), dr["taskname"].ToString(), (i + 1).ToString(), param.MfgOrderName, res.Result ? " 开卡成功！" : " 开卡失败，原因：" + res.Message));
            }
            //此任务执行完毕
            CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", string.Format(" 任务执行完毕，执行订单数：{0}，成功：{1}，失败：{2}", scount + ecount, scount, ecount), "1");
            LogHelp.WriteLog(string.Format("分厂：{0}，任务：{1} 执行完毕----------------------------------------------------------------------", dr["factoryname"].ToString(), dr["taskname"].ToString()));
        }

        /// <summary>
        /// 转换数据
        /// </summary>
        /// <param name="dr"></param>
        /// <returns></returns>
        private Tuple<AutoStartContainerParam, bool, string> GetOrderMappingData(DataRow dr)
        {
            try
            {
                AutoStartContainerParam param = new AutoStartContainerParam()
                {
                    MfgOrderID = dr["mfgorderid"].ToString(),
                    MfgOrderName = dr["mfgordername"].ToString(),
                    ProductName = dr["productname"].ToString(),
                    ProductFamilyName = dr["productfamilyname"].ToString(),
                    UomName = dr["uomname"].ToString(),
                    AutoType = "自动"
                };
                if (!string.IsNullOrWhiteSpace(dr["plannedstartdate"].ToString()))
                {
                    param.PlannedStartDate = DateTime.Parse(dr["plannedstartdate"].ToString());
                }
                if (!string.IsNullOrWhiteSpace(dr["plannedcompletiondate"].ToString()))
                {
                    param.PlannedCompletionDate = DateTime.Parse(dr["plannedcompletiondate"].ToString());
                }
                if (!string.IsNullOrWhiteSpace(dr["qty"].ToString()))
                {
                    param.Qty = int.Parse(dr["qty"].ToString());
                }
                return new Tuple<AutoStartContainerParam, bool, string>(param, true, "");
            }
            catch (Exception ex)
            {
                return new Tuple<AutoStartContainerParam, bool, string>(null, false, ex.Message);
            }
        }
    }
}
